//
//  StackDictionary.m
//  Source List
//
//  Created by Keith Duncan on 28/01/2009.
//  Copyright 2009 thirty-three software. All rights reserved.
//

#import "AFStackDictionary.h"

@implementation AFStackDictionary

- (id)init {
	self = [super init];
	
	keys = [[NSPointerArray pointerArrayWithStrongObjects] retain];
	objects = [[NSPointerArray pointerArrayWithStrongObjects] retain];
	
	return self;
}

- (void)dealloc {
	[keys release];
	[objects release];
	
	[super dealloc];
}

- (NSUInteger)count; {
	return [keys count];
}

- (id)objectForKey:(id)key; {
	NSUInteger index = [[keys allObjects] indexOfObject:key];
	return (index == NSNotFound) ? nil : [objects pointerAtIndex:index];
}

- (void)removeObjectForKey:(id)key {
	NSUInteger index = [[keys allObjects] indexOfObject:key];
	if (index == NSNotFound) return;
	
	[keys removePointerAtIndex:index];
	[objects removePointerAtIndex:index];
	
	[keys compact];
	[objects compact];
}

- (void)setObject:(id)object forKey:(id)key {
	if ([keys count] != [objects count]) {
		[NSException raise:NSInternalInconsistencyException format:@"%s, in the middle of a key/object push operation - cannot set directly - behaviour undefined"];
		return;
	}
	
	[self pushKey:key];
	[self addObject:object];
}

- (void)_pushObject:(id)object array:(NSPointerArray *)array {
	if ((([keys count]+(array == keys ? 1 : 0)) != ([objects count]+ (array == objects ? 1 : 0))) && (([keys count]+1) != ([objects count]+1))) {
		[NSException raise:NSInternalInconsistencyException format:@""];
		return;
	}
	
	[array addPointer:object];
}

- (void)pushKey:(id <NSCopying>)key; {
	[self _pushObject:[[key copyWithZone:NULL] autorelease] array:keys];
}

- (void)addObject:(id)object; {
	[self _pushObject:object array:objects];
}

- (NSEnumerator *)keyEnumerator; {
	if ([keys count] != [objects count]) {
		[NSException raise:NSInternalInconsistencyException format:@"%s, in the middle of a key/object push operation - cannot enumerate keys - behaviour undefined"];
		return nil;
	}
	
	return [[keys allObjects] objectEnumerator];
}

@end
